using ContentRenderingApi.Data;
using System.Collections.Generic;
using Com.ContentRendering.Api.DataEngine;

namespace ContentRenderingApi.Extender
{
    /// <summary/>
    public class NodeExtender
    {
        private AbstractData _data;

        /// <summary/>
        internal NodeExtender(AbstractData data)
        {
            this._data = data;
        }

        /// <summary/>
        public NodeExtender Parent 
        {
            get 
            { 
                // return nothing if the parent is not set
                if (this._data.Parent == null)
                {
                    return null;
                }
                
                return new NodeExtender(this._data.Parent); 
            }
        }

        /// <summary/>
        public NodeExtender[] FetchChildNodes(string name)
        {
            IEnumerator<AbstractData> enumerator = this._data.FetchChildData(name);

            List<NodeExtender> values = new List<NodeExtender>();

            while (enumerator.MoveNext())
            {
                values.Add(new NodeExtender(enumerator.Current));
            }

            // return the nodes as an array
            return values.ToArray();
        }

        /// <summary/>
        public int FetchChildLength(string name)
        {
            IEnumerator<AbstractData> enumerator = this._data.FetchChildData(name);

            int length = 0;

            while (enumerator.MoveNext())
            {
                length++;
            }

            // return the length
            return length;
        }

        /// <summary/>
        public NodeExtender[] FetchRootNodes(string name)
        {
            IEnumerator<AbstractData> enumerator = this._data.FetchRootData(name);
            
            List<NodeExtender> values = new List<NodeExtender>();

            while (enumerator.MoveNext())
            {
                values.Add(new NodeExtender(enumerator.Current));
            }

            // return the nodes as an array
            return values.ToArray();
        }

        /// <summary/>
        public int FetchRootLength(string name)
        {
            IEnumerator<AbstractData> enumerator = this._data.FetchRootData(name);

            int length = 0;

            while (enumerator.MoveNext())
            {
                length++;
            }

            // return the length
            return length;
        }

        /// <summary/>
        public object FetchRawProperty(string name)
        {
            return PropertyReflection.Translate(this._data.ReflectionCache, this._data.RawValue, name);
        }

        /// <summary/>
        public T FetchRawProperty<T>(string name)
        {
            object propertyValue = PropertyReflection.Translate(this._data.ReflectionCache, this._data.RawValue, name);

            // return the default
            if (propertyValue == null)
            {
                return default(T);
            }

            return (T)propertyValue;
        }

        /// <summary/>
        public object RawValue 
        {
            get { return this._data.RawValue; }
        }

        /// <summary/>
        public int Position
        {
            get { return this._data.Position; }
        }

        /// <summary/>
        public int Length
        {
            get { return this._data.Length; }
        }
    }
}
